{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**AoS**（Array of Structures，结构体数组）\n",
    "- 定义：以“对象”为单位连续存储，每个元素是一个包含多个字段的结构体。\n",
    "- 特点：按对象处理友好；当只使用其中少数字段时，会加载不必要的数据，影响带宽和缓存命中；对向量化不友好。\n",
    "- 简图：\n",
    "  - 内存布局：`| x y z w | x y z w | x y z w | ...`"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**SoA**（Structure of Arrays，数组的结构）\n",
    "- 定义：按“字段”分别存储，每个字段一个数组，下标对齐。\n",
    "- 特点：当按字段批量处理时更利于缓存与带宽利用；更易被自动向量化；对象操作稍复杂。\n",
    "- 简图：\n",
    "  - 内存布局：\n",
    "    - `x: | x x x x ... |`\n",
    "    - `y: | y y y y ... |`\n",
    "    - `z: | z z z z ... |`\n",
    "    - `w: | w w w w ... |`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "cpp"
    }
   },
   "outputs": [],
   "source": [
    "// 向量化示意\n",
    "\n",
    "// AoS：跨结构体步长访问，往往需要 gather 或 shuffle\n",
    "// 假设要批量处理 x 字段（示意，实际编译器可能还需额外指令）\n",
    "__m256 xi = _mm256_i32gather_ps(&aos[0].x, _mm256_setr_epi32(i+0,i+1,i+2,i+3,i+4,i+5,i+6,i+7),\n",
    "                                sizeof(ParticleAoS));\n",
    "// 后续还需处理 y/z/w 混排带来的 shuffle\n",
    "\n",
    "// SoA：字段连续，可直接流式装载/存储\n",
    "__m256 x = _mm256_loadu_ps(&soa.x[i]);\n",
    "__m256 y = _mm256_loadu_ps(&soa.y[i]);\n",
    "// ... 计算后\n",
    "_mm256_storeu_ps(&soa.x[i], x);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "| 维度 | AoS（结构体数组） | SoA（数组的结构） | 影响 |\n",
    "|---|---|---|---|\n",
    "| 内存布局 | 每个元素的多字段交错存放 | 按字段分别连续存放 | 访问单一字段时，SoA 连续性更好 |\n",
    "| 缓存行有效载荷 | 低：同载入带来大量未用字段 | 高：载入几乎全是所需字段 | SoA 降低无效带宽占用 |\n",
    "| 自动向量化 | 难：步长大，需 gather/shuffle | 易：连续 load/store | SoA SIMD 指令利用率更高 |\n",
    "| 预取/顺序性 | 多条混合流，stride 较大 | 每字段单一线性流 | SoA 预取效果更稳定 |\n",
    "| 冗余内存流量 | 高：用 x 也会拖入 y/z/w/mass | 低：只加载所需字段数组 | SoA 在带宽受限内核中更快 |\n",
    "| 异构类型影响 | double 与 float 混排放大步长与填充 | 各自数组独立、对齐最优 | SoA 便于选择合适向量宽度 |\n",
    "| 工作集与 TLB | 分散、占用更大 | 紧凑、命中率更高 | SoA 减少缺页与缓存抖动 |\n",
    "| 适用工作负载 | 按对象整体频繁读写 | 按字段批处理/归约/筛选 | 访问模式决定更优布局 |\n",
    "| 可维护性/接口 | 面向对象直观 | 需管理多个数组的下标 | 取舍在性能与易用性之间 |\n",
    "| 你的基准结果 | ≈278.741M items/s | ≈574.403M items/s | SoA ≈ 2.06× AoS |\n",
    "\n",
    "结论：当按字段批量处理时，SoA 通常显著快于 AoS；当以对象为单位整体操作时，AoS 更自然。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- 任务：对四个 float 字段执行融合算子（FMA 类似的线性组合）并归约出校验和，防止被优化掉。\n",
    "- 数据规模：默认 N=2,000,000（可按需调整）。\n",
    "- 编译：开启 -O3 -march=native 以触发自动向量化。\n",
    "- 指标：总耗时、吞吐（元素/秒）、相对加速比。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "shellscript"
    }
   },
   "outputs": [],
   "source": [
    "! rm -fr build"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "vscode": {
     "languageId": "shellscript"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2025-10-15T09:24:33+08:00\n",
      "Running ./build/aos_soa_bench\n",
      "Run on (16 X 3792.93 MHz CPU s)\n",
      "CPU Caches:\n",
      "  L1 Data 32 KiB (x8)\n",
      "  L1 Instruction 32 KiB (x8)\n",
      "  L2 Unified 1024 KiB (x8)\n",
      "  L3 Unified 16384 KiB (x1)\n",
      "Load Average: 0.12, 0.06, 0.02\n",
      "-----------------------------------------------------------------------------------\n",
      "Benchmark                         Time             CPU   Iterations UserCounters...\n",
      "-----------------------------------------------------------------------------------\n",
      "BM_AoS/N:2000000/iters:5   35876821 ns     35875659 ns           20 items_per_second=278.741M/s\n",
      "BM_SoA/N:2000000/iters:5   17411356 ns     17409366 ns           46 items_per_second=574.403M/s\n"
     ]
    }
   ],
   "source": [
    "! g++ -O3 -march=native -DNDEBUG -std=c++17 bm_bench.cpp bench.cpp -lbenchmark -lpthread -o build/aos_soa_bench && ./build/aos_soa_bench"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "C++17",
   "language": "C++17",
   "name": "xcpp17"
  },
  "language_info": {
   "codemirror_mode": "text/x-c++src",
   "file_extension": ".cpp",
   "mimetype": "text/x-c++src",
   "name": "c++",
   "version": "17"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
